package com.iotcomm.protocol;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 消息协议定义类
 * 定义了客户端和服务器之间通信的消息格式
 */
public class Message {
    // 消息类型常量
    public static final byte LOGIN = 0x01;          // 登录请求
    public static final byte LOGIN_RESPONSE = 0x02; // 登录响应
    public static final byte LOGOUT = 0x03;         // 登出请求
    public static final byte PRIVATE_CHAT = 0x04;   // 私聊消息
    public static final byte BROADCAST = 0x05;      // 广播消息
    public static final byte USER_LIST = 0x06;      // 用户列表更新
    public static final byte HEARTBEAT = (byte) 0x88; // 心跳包
    public static final byte ERROR = (byte) 0xFF;   // 错误消息
    
    @JsonProperty("messageType")
    private byte messageType;
    
    @JsonProperty("sender")
    private String sender;
    
    @JsonProperty("receiver")
    private String receiver;
    
    @JsonProperty("timestamp")
    private String timestamp;
    
    @JsonProperty("content")
    private String content;
    
    @JsonProperty("messageLength")
    private int messageLength;
    
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 默认构造函数
     */
    public Message() {
        this.timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    
    /**
     * 构造函数
     * @param messageType 消息类型
     * @param sender 发送者
     * @param receiver 接收者
     * @param content 消息内容
     */
    public Message(byte messageType, String sender, String receiver, String content) {
        this();
        this.messageType = messageType;
        this.sender = sender;
        this.receiver = receiver;
        this.content = content;
        this.messageLength = content != null ? content.getBytes().length : 0;
    }
    
    /**
     * 将消息对象序列化为JSON字符串
     * @return JSON字符串
     */
    public String toJson() {
        try {
            return objectMapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("消息序列化失败", e);
        }
    }
    
    /**
     * 从JSON字符串反序列化为消息对象
     * @param json JSON字符串
     * @return 消息对象
     */
    public static Message fromJson(String json) {
        try {
            return objectMapper.readValue(json, Message.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("消息反序列化失败", e);
        }
    }
    
    /**
     * 创建心跳消息
     * @param sender 发送者
     * @return 心跳消息
     */
    public static Message createHeartbeat(String sender) {
        return new Message(HEARTBEAT, sender, null, "");
    }
    
    /**
     * 创建登录消息
     * @param username 用户名
     * @return 登录消息
     */
    public static Message createLogin(String username) {
        return new Message(LOGIN, username, null, username);
    }
    
    /**
     * 创建私聊消息
     * @param sender 发送者
     * @param receiver 接收者
     * @param content 消息内容
     * @return 私聊消息
     */
    public static Message createPrivateChat(String sender, String receiver, String content) {
        return new Message(PRIVATE_CHAT, sender, receiver, content);
    }
    
    /**
     * 创建广播消息
     * @param sender 发送者
     * @param content 消息内容
     * @return 广播消息
     */
    public static Message createBroadcast(String sender, String content) {
        return new Message(BROADCAST, sender, "ALL", content);
    }
    
    // Getter和Setter方法
    public byte getMessageType() {
        return messageType;
    }
    
    public void setMessageType(byte messageType) {
        this.messageType = messageType;
    }
    
    public String getSender() {
        return sender;
    }
    
    public void setSender(String sender) {
        this.sender = sender;
    }
    
    public String getReceiver() {
        return receiver;
    }
    
    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }
    
    public String getTimestamp() {
        return timestamp;
    }
    
    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
    
    public String getContent() {
        return content;
    }
    
    public void setContent(String content) {
        this.content = content;
        this.messageLength = content != null ? content.getBytes().length : 0;
    }
    
    public int getMessageLength() {
        return messageLength;
    }
    
    public void setMessageLength(int messageLength) {
        this.messageLength = messageLength;
    }
    
    @Override
    public String toString() {
        return String.format("Message{type=%02X, sender='%s', receiver='%s', timestamp='%s', content='%s'}",
                messageType, sender, receiver, timestamp, content);
    }
}